#include "lcd12864.h"   
#include "delay.h" 


//逐行式，阴码，顺向


 /**
  * @brief  初始化控制LED的IO
  * @param  无
  * @retval 无
  */
void LCD1602_GPIO_Config(void)
{		
	/*定义一个GPIO_InitTypeDef类型的结构体*/
	GPIO_InitTypeDef GPIO_InitStructure;

	/*开启LED相关的GPIO外设时钟*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB,ENABLE);

	//LCD_E引脚初始化
	GPIO_InitStructure.GPIO_Pin = LCD1602_EN_PIN;	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
	GPIO_Init(LCD1602_EN_PORT, &GPIO_InitStructure);	
	
	//LCD_RW引脚初始化
	GPIO_InitStructure.GPIO_Pin = LCD1602_RW_PIN;
	GPIO_Init(LCD1602_RW_PORT, &GPIO_InitStructure);
	
	//LCD_RS引脚初始化
	GPIO_InitStructure.GPIO_Pin = LCD1602_RS_PIN;
	GPIO_Init(LCD1602_RS_PORT, &GPIO_InitStructure);
	
	//LCD_PSB引脚初始化
	GPIO_InitStructure.GPIO_Pin = LCD1602_PSB_PIN;
	GPIO_Init(LCD1602_PSB_PORT, &GPIO_InitStructure);
}

void LCD12864_Write_Byte(uint8_t data)
{
	uint8_t WBi;
	LCD1602_RS_H;
	for(WBi=0;WBi<8;WBi++)
	{
		(data<<WBi&0x80)?LCD1602_RW_H:LCD1602_RW_L;	//移位，判断高位
	
		LCD1602_E_L;	//拉低时钟
		LCD1602_E_H;	//拉高时钟
	}
	LCD1602_RS_L;		//释放片选，不再占据总线
}
	
/*LCD12864写函数 传入指令写指令，传入数据写数据*/
void LCD12864_Write_CMD_Data(uint8_t cmd,uint8_t data)
{
	LCD12864_Write_Byte(cmd);
	LCD12864_Write_Byte(data&0xf0);			//根据时序图，传入数据的高4位变成发送数据的高4位，发送的数据低4位为0。例0x38 0011 1000 & 1111 0000
	LCD12864_Write_Byte((data<<4)&0xf0);	//再取传入数据的低4位，变成发送数据的高4位，发送的数据低4位为0。例0x38<<4 1000 & 1111 0000
	Delay_ms(2);	//设置传输延时
}

//显示字符初始化函数
void initinal(void)           //LCD字库初始化程序
{		
	LCD1602_PSB_L;							//设置串行通讯
	LCD12864_Write_CMD_Data(CMD,0x30);		//功能设定，8位MCU接口，基本指令集
	LCD12864_Write_CMD_Data(CMD,0x06);		//显示数据的读写时，设定游标方向右移，DDRAM地址计数器加1
	LCD12864_Write_CMD_Data(CMD,0x0C);		//开显示，关闭光标
	LCD12864_Write_CMD_Data(CMD,0x01);		//清除显示
	LCD12864_Write_CMD_Data(CMD,0x80);		//设置启动位置

}


void LCD_SetCursor(uint8_t Line, uint8_t Column)
{
	if(Line == 1)
		LCD12864_Write_CMD_Data(CMD,0x80 | (Column-1));
	
	else if(Line == 2)
		LCD12864_Write_CMD_Data(CMD,0x90 | (Column-1));
	else if(Line == 3)
		LCD12864_Write_CMD_Data(CMD,0x88 | (Column-1));
	else if(Line == 4)
		LCD12864_Write_CMD_Data(CMD,0x98 | (Column-1));
}


void LCD_ShowString(uint8_t Line, uint8_t Column, uint8_t *String) 
{
	unsigned char i;
    LCD_SetCursor(Line,Column);
    
	for(i=0;String[i]!='\0';i++)
		LCD12864_Write_CMD_Data(DAT,String[i]);
}

void LCD_ShowChinese(uint8_t Line, uint8_t Column, uint8_t *String) 
{
	unsigned char i;
    LCD_SetCursor(Line,Column);
    
	for(i=0;String[i]!='\0';i++)
		LCD12864_Write_CMD_Data(DAT,String[i]);
}

int LCD_Pow(int X,int Y)
{
	unsigned char i;
	int Result=1;
	for(i=0;i<Y;i++)
	{
		Result*=X;
	}
	return Result;
}

void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
	unsigned char i;
	LCD_SetCursor(Line,Column);
	for(i=Length;i>0;i--)
	{
		LCD12864_Write_CMD_Data(DAT,Number/LCD_Pow(10,i-1)%10+'0');
	}
}


//显示图片函数
void DisplayGraphic(unsigned char  *adder)
{

	int i,j;
	//*******显示上半屏内容设置
	for(i=0;i<32;i++)              //
	{ 
		LCD12864_Write_CMD_Data(CMD,(0x80 + i));
		LCD12864_Write_CMD_Data(CMD,0x80);
	
		for(j=0;j<16;j++)
		{
			
			LCD12864_Write_CMD_Data(DAT,*adder);
			adder++;
		}
	}	   
	//*******显示下半屏内容设置
	for(i=0;i<32;i++)              //
	{
		LCD12864_Write_CMD_Data(CMD,(0x80 + i));
		LCD12864_Write_CMD_Data(CMD,0x80);
		for(j=0;j<16;j++)
		{
			LCD12864_Write_CMD_Data(DAT,*adder);
			adder++;
		}
	}
}

void LCD12864_Init(void)
{
	LCD1602_GPIO_Config();	
	LCD1602_PSB_L;       //设置为8BIT并口工作模式
	initinal();   		 //调用LCD字库初始化程序
}
